""" sbak.widget - Implementation of widgets for GUI application dev.

    ~~~ How to Use This Package ~~~

    Classes and functions available in this package are
    implemented in various submodules, but it is recommended that you
    access them as members of `sbak.widget` itself rather than as
    members of the submodules. This is because the submodule
    organization is considered more of an implementation detail rather
    than a method of API organization, and is subject to change. For
    the purposes of the library user, consider all classes to be in the
    same namespace.
    
    In other words, do this:
    
    >>> import sbak.widget          # Right!
    >>> foo = sbak.widget.Foo()     # Right!
    
    Not this:
    
    >>> import sbak.widget.foo_module       # WRONG!
    >>> foo = sbak.widget.foo_module.Foo()  # WRONG!
    
    Also, it should be safe to do `from sbak.widget import *`, but be
    aware that this will import the `init()` function, which may
    conflict with the init()'s of other other modules imported using
    `from ... import *` syntax.

    ~~~ Dirtiness ~~~

    For the purposes of this module, "dirty" means "state has been
    changed and redrawing is needed." Also, the term "smudge" means
    "to make (mark) dirty".
    
    ~~~ Drawing and Displaying ~~~
    
    Here, a distinction must be made between "displaying" and "drawing."
    The difference is subtle, but important.
    
    "Drawing" is perhaps more easy to understand and will be more
    familiar to most people: When an object is "drawn," that means the
    representative imagery for the object (such as an icon, or text) is
    made to appear at a specific position on some target drawing
    surface.
    
    Drawing disregards the internal position of the object
    being drawn (ie. the place where the object "thinks" it is located,
    if any) and instead uses only the position given at the time of
    drawing. Additionally, most objects that support drawing also
    support "regional drawing," a scenario in which only a certain
    rectangular region of the object's imagery is drawn, but not the
    whole thing.
    
    "Displaying" is somewhat harder to understand. It is a variant of
    drawing in which the location at which to draw the object, and
    possibly the target surface as well, are known before the drawing
    actually occurs. When an object is displayed, it is drawn at a
    location on the surface, but the location is determined by the
    object rather than by the displayer. Oftentimes the object being
    displayed will decide what surface to be displayed on as well
    (though not always).
    
    Sometimes an offset may be given by the displayer when it displays
    the object. This is akin to the position that is specified during a
    draw, except that it is interpreted relative to the displayed
    object's actual position. This may seem to blur the lines between
    "drawing" and "displaying," but keep in mind that in the case of a
    draw, the object's actual position is not important, but during a
    "display," it is.
    
    Finally, a region may be specified for displaying, just as with
    drawing. In the case of displaying, however, the region given
    indicates the target region rather than the source region--in other
    words, the region corresponds to an area on the destination surface
    rather than an area within the object being displayed. This is
    given more for the benefit of the displayed object rather than the
    displayer. What a displayed object does with the region is up
    to the object.
    
    TODO: Rename the `full` argument to `fullscreen` in Desktop.
"""

import pygame

#from style import *
from base import *
from container import *
from window import *
from layout import *
from control import *

__all__ = [
    'DEFAULT_WIDGET_REGION',
    'DEFAULT_WINDOW_REGION',
#    'DEFAULT_BASE_STYLE',
    
#    'Style',
    'AbstractWidget',
    'Widget',
    
    'AbstractContainer',
    'Container',
    
    'Window',
    'Desktop',
    'Form',
    'Panel',

    'LayoutMixin',
    'LayoutContainer',
    'LayoutWindow',
    'LayoutDesktop',
    
    'Button'
]

# Whether or not the widget module has been initialized.
_init = False

def init():
    """ Initializes the `sbak.widget` module.
    
        Some functionality of the widget module will not work until
        the module is completely initialized, but there are a few
        things that cannot be properly initialized at import time.
        For this reason, a portion of the module's initialization is
        deferred to this function.
        
        It is good practice to always call this function before using
        any other part of the `widget` module, even if you don't think
        you will be using the parts that aren't initialized at import
        time.
        
        This function is NOT called by `sbak.init()` because
        `sbak.widget` is considered an auxillary module. For this
        reason, remember to explicitly call `sbak.widget.init()` after
        calling `sbak.init()` if you intend to use the widget module
        in your application.
        
        It is safe to call this multiple times; calls after the first
        call will do nothing.
        
        This function will fail if the `pygame.font` module is not
        available.
    """
    global _init
    if not _init:
        #import style
        #style.init()
        _init = True
